package com.zmn.oms.third.toutiao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.third.ToutiaoCompanyAccountService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.HttpUtil;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.order.create.CreateOrderFailMessage;
import com.zmn.oms.model.dto.order.proxy.CreateOrderDTO;
import com.zmn.oms.model.dto.product.ChannelProductMapDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.entity.third.ToutiaoCompanyAccount;
import com.zmn.oms.model.entity.trace.ToutiaoOrderTrace;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.services.interfaces.order.OrderChangeService;
import com.zmn.oms.services.interfaces.trace.ChannelOrderTraceService;
import com.zmn.oms.third.base.util.ThirdOrderUtil;
import com.zmn.oms.third.toutiao.HeadlinesConsts;
import com.zmn.oms.third.toutiao.dto.HeadlinesOrderResultData;
import com.zmn.oms.third.toutiao.util.SHAUtil;
import com.zmn.oms.zmn.business.interfaces.discount.ChannelDiscountService;
import com.zmn.oms.zmn.business.interfaces.product.ProductMappingBService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.pay.common.constant.PayConsts;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author: huangyifeng
 * @description: 头条接入
 * @create: 2019-12-20 15:08
 **/
@Service
public class HeadlinesServiceImpl extends HeadlinesBase {

    private static final Logger logger = LoggerFactory.getLogger(HeadlinesServiceImpl.class);

    private static final int REDIS_TIME_OUT = 60 * 60 * 24; // 1天

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected AreaListRemoteService areaListRemoteService;
    @Autowired
    private ProxyOrderBService proxyOrderBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private OrderChangeService orderChangeService;
    @Autowired
    private ToutiaoCompanyAccountService toutiaoCompanyAccountService;
    @Autowired
    private BaiduMapBService baiduMapBService;
    @Autowired
    private ChannelDiscountService channelDiscountService;
    @Autowired
    private ChannelOrderTraceService channelOrderTraceService;
    @Autowired
    private ProductMappingBService productMappingBService;
    @Resource
    private RedisManager redisManager;

    /**
     * 增加头条平台公司账号信息
     * @param companyAccount
     */
    @Override
    public void addCompanyAccount(ToutiaoCompanyAccount companyAccount) {
        if (Objects.isNull(companyAccount)) {
            return;
        }

        toutiaoCompanyAccountService.insertCompanyAccount(companyAccount);
    }

    /**
     *  删除头条平台公司账号信息
     * @param secret
     */
    @Override
    public void delCompanyAccount(String secret) {
        if (StringUtil.isBlank(secret)) {
            return;
        }

        toutiaoCompanyAccountService.deleteCompanyAccountByKey(secret);
    }

    /**
     * 获取头条线索订单
     */
    @Override
    public void findHeadlinesOrder(Date time) {
        // 是否到开启时间
        if(!HeadlinesConsts.findStartUpTime()){
            return;
        }

        this.pullOrderData(time);

        /*
        try {
            int channel_A = HeadlinesConsts.CHANNEL_ID_A;
            Map<String, String> account = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_A;
            ergodicData(account, channel_A, time);

            int channel_B = HeadlinesConsts.CHANNEL_ID_B;
            Map<String, String> accountB = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_B;
            ergodicData(accountB, channel_B, time);

            int channel_C = HeadlinesConsts.CHANNEL_ID_C;
            Map<String, String> accountC = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_C;
            ergodicData(accountC, channel_C, time);

            int channel_D = HeadlinesConsts.CHANNEL_ID_D;
            Map<String, String> accountD = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_D;
            ergodicData(accountD, channel_D, time);

            int channel_INFO_BIZ_A = HeadlinesConsts.CHANNEL_ID_INFO_BUSINESS_A;
            Map<String, String> accountInfoBizA = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_BUSINESS_A;
            ergodicData(accountInfoBizA, channel_INFO_BIZ_A, time);

            int channel_BIZ_A = HeadlinesConsts.CHANNEL_ID_BUSINESS_A;
            Map<String, String> accountBizA = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_BUSINESS_A;
            ergodicData(accountBizA, channel_BIZ_A, time);

            int channel_INFO_A = HeadlinesConsts.CHANNEL_ID_INFO_A;
            Map<String, String> accountInfoA = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_A;
            ergodicData(accountInfoA, channel_INFO_A, time);

            int channel_INFO_B = HeadlinesConsts.CHANNEL_ID_INFO_B;
            Map<String, String> accountInfoB = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_B;
            ergodicData(accountInfoB, channel_INFO_B, time);

            int channel_INFO_C = HeadlinesConsts.CHANNEL_ID_INFO_C;
            Map<String, String> accountInfoC = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_C;
            ergodicData(accountInfoC, channel_INFO_C, time);

            int channel_INFO_C_1 = HeadlinesConsts.CHANNEL_ID_INFO_C_1;
            Map<String, String> accountInfoC1 = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_C_1;
            ergodicData(accountInfoC1, channel_INFO_C_1, time);

            int channel_INFO_D = HeadlinesConsts.CHANNEL_ID_INFO_D;
            Map<String, String> accountInfoD = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_D;
            ergodicData(accountInfoD, channel_INFO_D, time);

            int channel_INFO_F = HeadlinesConsts.CHANNEL_ID_INFO_F;
            Map<String, String> accountInfoF = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_F;
            ergodicData(accountInfoF, channel_INFO_F, time);

            int channel_INFO_G = HeadlinesConsts.CHANNEL_ID_INFO_G;
            Map<String, String> accountInfoG = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_G;
            ergodicData(accountInfoG, channel_INFO_G, time);

            int channel_INFO_D_HL = HeadlinesConsts.CHANNEL_ID_INFO_D_HL;
            Map<String, String> accountInfoDHL = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_INFO_D_HL;
            ergodicData(accountInfoDHL, channel_INFO_D_HL, time);

            int channel_B_01 = HeadlinesConsts.CHANNEL_ID_B_01;
            Map<String, String> accountB01 = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_B_01;
            ergodicData(accountB01, channel_B_01, time);

            int channel_B_02 = HeadlinesConsts.CHANNEL_ID_B_02;
            Map<String, String> accountB02 = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_B_02;
            ergodicData(accountB02, channel_B_02, time);

            int channel_JD_A = HeadlinesConsts.CHANNEL_ID_JD_A;
            Map<String, String> accountJDA = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_JD_A;
            ergodicData(accountJDA, channel_JD_A, time);

            int channel_JD_B = HeadlinesConsts.CHANNEL_ID_JD_B;
            Map<String, String> accountJDB = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_JD_B;
            ergodicData(accountJDB, channel_JD_B, time);

            int channel_JD_C = HeadlinesConsts.CHANNEL_ID_JD_C;
            Map<String, String> accountJDC = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_JD_C;
            ergodicData(accountJDC, channel_JD_C, time);

            int channel_JD_D = HeadlinesConsts.CHANNEL_ID_JD_D;
            Map<String, String> accountJDD = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_JD_D;
            ergodicData(accountJDD, channel_JD_D, time);

            int channel_JD_E = HeadlinesConsts.CHANNEL_ID_JD_E;
            Map<String, String> accountJDE = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_JD_E;
            ergodicData(accountJDE, channel_JD_E, time);

            int channel_JD_F = HeadlinesConsts.CHANNEL_ID_JD_F;
            Map<String, String> accountJDF = HeadlinesConsts.ACCOUNT_SECRET_KEY_MAP_JD_F;
            ergodicData(accountJDF, channel_JD_F, time);

        } catch (OmsBaseException e) {
            logger.error(String.format("[%s] 获取头条数据失败[%s]", HeadlinesConsts.HEADLINES, e.getMessage()), e);
        }
         */
    }

    /**
     * 遍历账户数据,拉取订单线索，并创建订单
     * @param time
     */
    private void pullOrderData(Date time) {

        // 读取账户数据
        List<ToutiaoCompanyAccount> companyAccountList = this.getCompanyAccountList();
        if (CollectionUtil.isNullOrEmpty(companyAccountList)) {
            logger.error(String.format("[%s] 获取头条数据失败 - 平台账号信息列表为空", HeadlinesConsts.HEADLINES));
            return;
        }

        // 遍历账户数据
        companyAccountList.forEach (toutiaoCompanyAccount ->{

            // 拉取线索数据
            List<HeadlinesOrderResultData> clueList;
            try {
                clueList = pullCluesData(toutiaoCompanyAccount.getSecret(),
                        toutiaoCompanyAccount.getToken(), time);
            } catch (OmsBaseException omsBaseException) {
                logger.error(String.format("[%s] 拉取线索单失败：%s", HeadlinesConsts.HEADLINES, omsBaseException.getMessage()));
                return;
            }

            Integer channelId = toutiaoCompanyAccount.getChannelId();
            clueList = filterDuplicateClues(clueList,channelId);

            // 保存
            for (HeadlinesOrderResultData item : clueList) {
                try {
                    // 添加订单
                    saveNewOrder(item, channelId);
                } catch (Exception e) {
                    logger.error(String.format("[%s] 保存线索单失败：%s", HeadlinesConsts.HEADLINES, e.getMessage()));
                }
            }
        });
    }

    /**
     * 遍历账户数据,拉取订单线索，并创建订单
     *
     * @param account
     * @param channelId
     * @param time
     * @throws OmsBaseException
     */
    private void ergodicData(Map<String, String> account, int channelId, Date time) throws OmsBaseException {

        for (String encryptKey : account.keySet()) {

            // 拉取线索数据
            List<HeadlinesOrderResultData> clueList = pullCluesData(encryptKey, account.get(encryptKey), time);
            clueList = filterDuplicateClues(clueList, channelId);

            // 保存
            for (HeadlinesOrderResultData item : clueList) {
                try {
                    // 添加订单
                    saveNewOrder(item, channelId);
                } catch (Exception e) {
                    logger.error(String.format("[%s] 保存线索单失败：%s", HeadlinesConsts.HEADLINES, e.getMessage()), e);
                }
            }
        }
    }

    /**
     * 去除重复线索
     *
     * @param clueList
     * @param channelId
     * @return
     */
    private List<HeadlinesOrderResultData> filterDuplicateClues(List<HeadlinesOrderResultData> clueList, int channelId) {
        List<HeadlinesOrderResultData> list = new LinkedList<>();

        for (HeadlinesOrderResultData item : clueList) {
            Date createTime = new Date();
            if (StringUtils.isNotBlank(item.getCreateTime())) {
                createTime = DateUtil.parse(Long.valueOf(item.getCreateTime()));
            }

            String redisKey = String.format(RedisKeyConsts.TOUTIAO_REDIS_KEY_CLUE, channelId, item.getClueId());
            boolean isExists = redisManager.exists(redisKey);

            if (isExists) {
                // 忽略已拉取的线索信息
                continue;
            }

            redisManager.setex(redisKey, DateUtil.toString(createTime), REDIS_TIME_OUT);
            list.add(item);
        }

        return list;
    }

    /**
     * 生成创建订单需要的数据
     *
     * @param resultData
     * @return
     */
    private CreateOrderDTO buildOrderDTO(HeadlinesOrderResultData resultData, Integer channelId){

        if(!Objects.equals(resultData.getClueType(), 0)){
            logger.info("今日头条订单只拉取表单提交数据");
            return null;
        }

        CreateOrderDTO createOrderDTO = new CreateOrderDTO();

        Integer servCategId = OrderConsts.CHANNEL_DISABLED_PRODUCT_ID;
        boolean isShowProduct = false; // 默认前台产品

        String remarkDict = getJsonValue(resultData, HeadlinesConsts.REPAIR);   // 通过个别汉字获取头条的值
        if(StringUtils.isNotBlank(remarkDict)){
            // 获取服务项
            String productName = remarkDict.substring(remarkDict.lastIndexOf(",") + 1, remarkDict.length());
            createOrderDTO.setProductClues(productName);

            do {

                // 先通过接口查询渠道产品映射
                List<ChannelProductMapDTO> channelProductMapDTOList = productMappingBService.listChannelProductMapping(channelId,productName,null);
                if (CollectionUtil.isNotNullOrEmpty(channelProductMapDTOList)) {
                    servCategId = channelProductMapDTOList.get(0).getProductId();
                    if (Objects.equals(channelProductMapDTOList.get(0).getShowType(), GlobalConsts.YES)) {
                        isShowProduct = true;
                    }
                    break;
                }

                // 1. 优先获取前台产品ID
                Integer showProductId = HeadlinesConsts.SHOW_PRODUCT_CODE.get(productName);
                if (showProductId != null) {
                    servCategId = showProductId;
                    isShowProduct = true;
                    break;
                }

                /** 后台产品不进行匹配，xiewenbing 2021/11/25
                String productIdStr = HeadlinesConsts.PRODUCT_CODE.get(productName);
                if(StringUtils.isNotBlank(productIdStr)){
                    servCategId = Integer.parseInt(productIdStr);  //获取产品id
                }
                **/
            } while (false);
        }

        // 将同步数据中的订单关键信息记录进日志中
        createOrderDTO.setOperatorLogRemark(String.format(
                "父订单编号：%s，服务子订单：%s，产品：%s；",
                resultData.getAdvId(), resultData.getClueId(),
                remarkDict));

        createOrderDTO.setContactName(resultData.getName());
        createOrderDTO.setOuterId(String.valueOf(resultData.getClueId()));
        createOrderDTO.setOuterData(JSON.toJSONString(resultData));
        createOrderDTO.setRemark(resultData.getRemark());

        // 联系电话
        createOrderDTO.setTelephone(resultData.getTelphone());

        // expectDate 预约时间，注意就近转化为：整点和半点
        String expectDate = resultData.getDate();
        if (StringUtils.isNotBlank(expectDate)) {
            Date dutyTime = DateUtil.parse(expectDate, DateUtil.FORMAT_DATE);
            // 忽略掉当前时间超过预约时间的情况，由线下去确定预约时间
            if (dutyTime.getTime() > System.currentTimeMillis()) {
                createOrderDTO.setDutyTime(DateUtil.round(dutyTime, DateUtil.UNIT_MINUTE));
            }
        }

        try {
            // 地址转换
            fillAddress(createOrderDTO, resultData);
            // 商品转换
            fillProductInfo(createOrderDTO, servCategId, isShowProduct);

        } catch (Exception e) {
            logger.error(String.format("[%s] ErrorMsg:[%s]", HeadlinesConsts.HEADLINES, e.getMessage()), e);
            return null;
        }

        createOrderDTO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        createOrderDTO.setGender(GlobalDict.GENDER_NO);
        createOrderDTO.setDisableDiscard(GlobalConsts.NO);
        createOrderDTO.setOperator("系统");
        createOrderDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        createOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        createOrderDTO.setInputType(OrderConsts.ORDER_INPUT_TYPE_API);

        // 优惠 - 2021/6/1 至 2021/9/1 优惠5元
        channelDiscountService.tbsTempDiscountFiveYuan(createOrderDTO);

        return createOrderDTO;
    }

    /**
     * 获取到头条value信息
     * @param resultData
     * @return
     */
    private String getJsonValue(HeadlinesOrderResultData resultData, String key){
        JSONObject remarkDictJson = JSONObject.parseObject(resultData.getRemarkDict());
        Map<String, String> remarkDictMap = getAllKey(remarkDictJson);
        String repair = remarkDictMap.get(key);
        return remarkDictJson.getString(repair);
    }

    /**
     * 补全订单地址：将头条订单地址转换成符合我们自己系统使用的地址信息
     *
     * @param orderDTO
     * @param resultData
     */
    private void fillAddress(CreateOrderDTO orderDTO, HeadlinesOrderResultData resultData) {
        // buyerAddress格式中，省、市、区用空格分隔，例如：浙江省 宁波市 海曙区 石碶街道雅戈尔大道243号
        String province = Optional.ofNullable(resultData.getProvinceName()).orElse("");
        String city = Optional.ofNullable(resultData.getCityName()).orElse("");
        String address = Optional.ofNullable(getJsonValue(resultData, HeadlinesConsts.ADDRESS)).orElse("");   // 通过个别汉字获取头条的值

        String fullAddress = province + city + address;

        // 具体地址放入address
        orderDTO.setAddress(address);
        orderDTO.setStreet(""); // street字段在数据库中不能为空
        // 记录一下完整地址
        orderDTO.setOperatorLogRemark(orderDTO.getOperatorLogRemark() + fullAddress);
        // 记录线索中的完整地址信息，方便推送给呼叫中心
        orderDTO.setAddressClues(fullAddress);


        // 通过地址获取经纬度
        String locationAddress = fullAddress.replaceAll(" ", "");
        if (StringUtils.isNotBlank(locationAddress)) {
            LngLatLocation location = baiduMapBService.location(locationAddress);
            if (location != null) {
                Double lng = Double.valueOf(location.getLng());
                Double lat = Double.valueOf(location.getLat());

                try {
                    ResponseDTO<com.zmn.base.common.data.common.dro.area.AreaDRO> areaResponse = areaListRemoteService.getAreaByLatAndLng(lng, lat);
                    AreaDRO areaDRO = areaResponse.getData();
                    if (areaDRO != null) {
                        orderDTO.setCityId(areaDRO.getParentId());

                        orderDTO.setLatitude(lat);
                        orderDTO.setLongitude(lng);
                    }
                } catch (Exception e) {
                    logger.error(String.format("[%s] 使用经纬度获取CityId失败:[%s]", HeadlinesConsts.HEADLINES,
                            e.getMessage()), e);
                }
            }
        }
    }

    /**
     * 补全产品信息
     * @param zmnOrder
     * @param servCategId
     * @param isShowProductId
     */
    private void fillProductInfo(CreateOrderDTO zmnOrder, Integer servCategId, boolean isShowProductId) {
        OrderProductDTO orderProduct = new OrderProductDTO();
        orderProduct.setNumber(1);
        if (isShowProductId) {
            orderProduct.setShowProductId(servCategId);
            orderProduct.setProductShowType(GlobalConsts.YES);
        }
        else {
            orderProduct.setProductId(servCategId);
        }

        List<OrderProductDTO> list = new LinkedList<>();
        list.add(orderProduct);
        zmnOrder.setOrderProductList(list);

        zmnOrder.setChannelPrepayAmount(0);
        zmnOrder.setChannelPrepayStatus(PayConsts.PAY_STATUS_NONE);

        zmnOrder.setOperatorLogRemark(zmnOrder.getOperatorLogRemark());
    }

    /**
     * 递归读取所有的key
     *
     * @param jsonObject
     */
    private Map<String, String> getAllKey(JSONObject jsonObject) {
        Map<String, String> keyMap = Maps.newHashMap();
        Iterator<String> keys = jsonObject.keySet().iterator();// jsonObject.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            if(key.contains(HeadlinesConsts.ADDRESS)){
                keyMap.put(HeadlinesConsts.ADDRESS,key);
            }
            if(key.contains(HeadlinesConsts.REPAIR) || key.contains(HeadlinesConsts.REPAIR_2)) {
                keyMap.put(HeadlinesConsts.REPAIR,key);
            }
        }
        return keyMap;
    }

    /**
     * 拉取今日头条订单
     *
     * @param encryptKey
     * @param token
     * @return
     * @throws OmsBaseException
     */
    private List<HeadlinesOrderResultData> pullCluesData(String encryptKey ,String token, Date time)
            throws OmsBaseException {

        if (StringUtils.isBlank(encryptKey) || StringUtils.isBlank(token) || Objects.isNull(time)) {
            throw new OmsBaseException("params error");
        }

        logger.info("[{}] 拉取订单线[{}][{}][{}]", HeadlinesConsts.HEADLINES, encryptKey,token,DateUtil.toString(time));

        List<HeadlinesOrderResultData> result = new LinkedList<>();

        try {
            // 拼接加密参数
            String currDateStr = new SimpleDateFormat("yyyy-MM-dd").format(time);
            String timestamp = String.valueOf(new Date().getTime()/1000);
            String path = HeadlinesConsts.encryptionPath(currDateStr, currDateStr);

            Map<String, String> map = Maps.newHashMap();
            map.put("Content-Type", "application/json");
            map.put("Timestamp", timestamp);
            map.put("Signature", SHAUtil.sha256_HMAC(String.format("%s %s", path, timestamp), encryptKey));
            map.put("Access-Token", token);

            boolean hasMoreData = true;
            int page = 1;
            while (hasMoreData) {
                String url = HeadlinesConsts.HEADLINES_URL + path + "&page=" + page;

                String response = HttpUtil.doGet(url, map);

                JSONObject json = JSONObject.parseObject(response);
                if (!"success".equals(json.getString("status"))) {
                    logger.info("[{}] 拉取订单线索失败：Response=[{}]", HeadlinesConsts.HEADLINES, result);
                    break;
                }

                JSONArray jsonArr = JSONArray.parseArray(json.getString("data"));
                for (int i=0, len=jsonArr.size(); i<len; i++) {
                    HeadlinesOrderResultData item = JSONObject.parseObject(jsonArr.getString(i),
                            HeadlinesOrderResultData.class);
                    result.add(item);
                }

                // 如果累计已获取1000条线索（10条*100次），不再获取
                // 数据条数少于10条，表示没有更多线索数据了
                if (page++ >= 100 || jsonArr.size() < 10) {
                    hasMoreData = false;
                }
            }
        } catch (Exception e) {
            logger.error(String.format("[%s] 拉取订单线索失败：%s", HeadlinesConsts.HEADLINES, e.getMessage()), e);
            throw new OmsBaseException(e.getMessage());
        }

        return result;
    }

    /**
     * 保存新单
     *
     * @param data 头条数据
     * @param channelId 渠道id
     * @throws Exception
     */
    private void saveNewOrder(HeadlinesOrderResultData data, int channelId) throws Exception {
        CreateOrderDTO createOrderDTO = null;
        String outerId = String.valueOf(data.getClueId());

        // 校验是不是重复的订单消息
        ZsOrderWorkVO zsOrderWorkVO = queryOrderByOuterId(outerId);
        if (zsOrderWorkVO != null) {
            logger.info("[{}] 重复的消息数据（已忽略） OuterId:[{}]", HeadlinesConsts.HEADLINES, outerId);
            return;
        }

        if(StringUtils.isBlank(data.getTelphone())){
            logger.info("[{}] 无电话号码数据（已忽略）OuterId:[{}]", HeadlinesConsts.HEADLINES, outerId);
            return;
        }

        logger.info("[{}] 保存订单数据 [{}]", HeadlinesConsts.HEADLINES, JSON.toJSONString(data));
        createOrderDTO = buildOrderDTO(data, channelId);
        if (Objects.isNull(createOrderDTO)) {
            logger.info("[{}] 生成创建订单数据失败，OuterId:[{}]", HeadlinesConsts.HEADLINES, outerId);
            return;
        }

        // 保存订单
        createOrderDTO.setChannelId(channelId);
        createOrderDTO.setOuterId(outerId);

        // 线索中：电话、地址、产品信息都有，保存订单
        if (ThirdOrderUtil.isOrderInfoIntact(createOrderDTO)) {
            logger.info("[{}] 添加新订单 CreateOrderDTO=[{}]", HeadlinesConsts.HEADLINES,
                    JSON.toJSONString(createOrderDTO));

            OrderBO orderBO = proxyOrderBService.createOrder(createOrderDTO);
            OrderWork orderWork = orderBO.getOrderWork();

            logger.info("[{}] 添加新订单成功 OrderId:[{}]", HeadlinesConsts.HEADLINES, orderWork.getOrderId());

            // 保存订单渠道溯源数据
            ToutiaoOrderTrace toutiaoOrderTrace = BeanMapper.map(data, ToutiaoOrderTrace.class);
            toutiaoOrderTrace.setOrderId(orderWork.getOrderId());
            toutiaoOrderTrace.setChannelId(channelId);
            channelOrderTraceService.addToutiaoOrderTrace(toutiaoOrderTrace);

            try {
                // 工单自动流转
                workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }

            return;
        }

        // 当线索数据中缺少以下任意条件：电话、地址、产品
        // 将线索转到呼叫中心去
        CreateOrderFailMessage createOrderFailMessage = new CreateOrderFailMessage();
        createOrderFailMessage.setChannelId(createOrderDTO.getChannelId());
        createOrderFailMessage.setTelephone(createOrderDTO.getTelephone());
        createOrderFailMessage.setContactName(createOrderDTO.getContactName());
        createOrderFailMessage.setAddress(createOrderDTO.getAddressClues());
        createOrderFailMessage.setProductName(createOrderDTO.getProductClues());
        createOrderFailMessage.setCityId(createOrderDTO.getCityId());
        createOrderFailMessage.setExtData(JSON.toJSONString(data));

        logger.info("[{}] 信息不全，推送至呼叫中心 CreateOrderFailMessage=[{}]", HeadlinesConsts.HEADLINES,
                JSON.toJSONString(createOrderFailMessage));
        orderChangeService.orderCreateFailSyncToApi(createOrderFailMessage);
    }

    /**
     * 从数据库中读取公司账号列表
     */
    protected List<ToutiaoCompanyAccount> getCompanyAccountList() {
        return toutiaoCompanyAccountService.listAllCompanyAccount();
    }
}
